# 高级功能实现
import asyncio
from playwright.async_api import async_playwright
import random

# 4.1 会话保持与状态管理
async def save_browser_state():
    """保存浏览器状态，避免重复登录"""
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        context = await browser.new_context()
        page = await context.new_page()
        
        # 手动登录过程...
        await page.goto('https://www.xiaohongshu.com')
        print("请在浏览器中完成登录...")
        
        # 等待登录完成（这里可以根据实际情况调整等待条件）
        input("登录完成后按回车键继续...")
        
        # 登录成功后保存状态
        await context.storage_state(path='xiaohongshu_auth.json')
        print("✅ 浏览器状态已保存到 xiaohongshu_auth.json")
        await browser.close()

async def use_saved_state():
    """使用保存的状态"""
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        context = await browser.new_context(storage_state='xiaohongshu_auth.json')
        page = await context.new_page()
        await page.goto('https://www.xiaohongshu.com')
        
        # 现在应该处于已登录状态
        try:
            await page.wait_for_selector('[data-testid="user-avatar"]', timeout=5000)
            print("✅ 使用保存状态成功登录")
            await page.screenshot(path='logged_in_with_saved_state.png')
        except:
            print("❌ 保存的状态可能已过期")
        
        await browser.close()

# 4.2 智能元素定位策略
class SmartLocator:
    def __init__(self, page):
        self.page = page
    
    async def smart_click(self, text):
        """使用多种选择器策略提高稳定性"""
        selectors = [
            f'button:has-text("{text}")',
            f'div:has-text("{text}")',
            f'//*[contains(text(), "{text}")]',
            f'[data-testid*="{text.lower()}"]'
        ]
        
        for selector in selectors:
            try:
                element = await self.page.wait_for_selector(selector, timeout=2000)
                await element.click()
                return True
            except:
                continue
        
        print(f"❌ 找不到文本为 {text} 的元素")
        return False

# 4.3 完整的错误处理与重试机制
async def robust_operation(operation, max_retries=3):
    """带重试机制的操作执行"""
    for attempt in range(max_retries):
        try:
            return await operation()
        except Exception as e:
            if attempt == max_retries - 1:
                raise e
            print(f"⚠️ 操作失败，第 {attempt + 1} 次重试: {e}")
            await asyncio.sleep(2 ** attempt)  # 指数退避

# 使用示例
async def demo_advanced_features():
    """演示高级功能"""
    print("=== 演示会话保持功能 ===")
    # await save_browser_state()  # 首次运行时取消注释
    # await use_saved_state()
    
    print("\n=== 演示智能定位功能 ===")
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        page = await browser.new_page()
        await page.goto('https://www.xiaohongshu.com')
        
        locator = SmartLocator(page)
        await locator.smart_click("登录")
        
        await browser.close()
    
    print("\n=== 演示重试机制 ===")
    async def failing_operation():
        if random.random() < 0.7:  # 70% 概率失败
            raise Exception("模拟操作失败")
        return "操作成功"
    
    try:
        result = await robust_operation(failing_operation)
        print(f"✅ {result}")
    except Exception as e:
        print(f"❌ 最终失败: {e}")

if __name__ == "__main__":
    asyncio.run(demo_advanced_features())
